<template>
  <div class="user-manager-container">
    <div class="dept-tree-container">
      <div class="dept-tree-tools">
        <svg-icon v-permission="['/system/dept/new']" class="tree-dept-tools" icon-class="tianjia2" @click="addNode(null)" />
      </div>
      <div class="dept-tree-container">
        <el-tree
          ref="deptTree"
          v-loading="loadingTree"
          :data="treeDatas"
          :props="defaultProps"
          node-key="id"
          default-expand-all
          :expand-on-click-node="false"
          :highlight-current="true"
          @node-click="clickdNode"
        >
          <template #default="{ node }">
            <span class="custom-tree-node">
              <span>{{ node.label }}</span>
              <span v-if="!!node.data.id">
                <svg-icon v-permission="['/system/dept/new']" class="tree-node-tools" icon-class="tianjia1" @click="addNode(node)" />
                <el-popconfirm
                  confirm-button-text="确认"
                  cancel-button-text="不用了"
                  icon="el-icon-info"
                  icon-color="red"
                  title="确定删除吗？"
                  @onConfirm="removeNode(node)"
                >
                  <svg-icon slot="reference" v-permission="['/system/dept/deleted']" class="tree-node-tools" icon-class="shanchu1" />
                </el-popconfirm>
                <svg-icon v-permission="['/system/dept/edited']" class="tree-node-tools" icon-class="tianxie" @click="editedNode(node)" />
              </span>
            </span>
          </template>
        </el-tree>
      </div>
    </div>
    <div class="manager-page-container">
      <div class="page-filter">
        <el-form :inline="true" :model="page.filter" class="demo-form-inline">
          <el-form-item label="昵称">
            <el-input v-model="page.filter.name" placeholder="输入用户名" />
          </el-form-item>
          <el-form-item label="账号">
            <el-input v-model="page.filter.account" placeholder="输入账号" />
          </el-form-item>
          <el-form-item label="电话">
            <el-input v-model="page.filter.phone" placeholder="输入电话" />
          </el-form-item>
          <el-form-item label="邮箱">
            <el-input v-model="page.filter.email" placeholder="输入邮箱" />
          </el-form-item>
        </el-form>
        <div class="page-filter-btns">
          <el-button type="primary" size="small" @click="refreshPageFilter">重置</el-button>
          <el-button type="primary" size="small" @click="submitPageFilter">查询</el-button>
        </div>
      </div>
      <div class="page-table">
        <div class="page-table-btns">
          <el-button v-permission="['/system/user/new']" type="primary" size="small" @click="newUserForm">新增</el-button>
        </div>
        <div ref="page-table-view" class="page-table-view">
          <el-table v-if="showTable" ref="page-table-el" v-loading="loadingTable" :height="tableHeight" border style="width: 100%" :data="page.records" @sort-change="sortChange">
            <el-table-column prop="account" label="账号" width="180" sortable="custom" />
            <el-table-column prop="name" label="昵称" width="180" sortable="custom" />
            <el-table-column prop="deptId" label="部门">
              <template #default="scope"> {{ mapDeptId2Name[scope.row.deptId] }}</template>
            </el-table-column>
            <el-table-column prop="roleIds" label="角色">
              <template #default="scope"> {{ (scope.row.roleIds || []).map(id => mapRoleId2Name[id]).join(",") }}</template>
            </el-table-column>
            <el-table-column prop="email" label="邮箱" />
            <el-table-column prop="phone" label="电话" sortable="custom" />
            <el-table-column prop="enable" label="可用" />
            <el-table-column prop="remark" label="备注" />
            <el-table-column fixed="right" label="Operations" width="120">
              <template #default="scope">
                <el-popconfirm
                  confirm-button-text="确认"
                  cancel-button-text="不用了"
                  icon="el-icon-info"
                  icon-color="red"
                  title="确定删除吗？"
                  @onConfirm="deletedUser(scope.row.id)"
                >
                  <el-button slot="reference" v-permission="['/system/user/deleted']" type="text" size="small">delete</el-button>
                </el-popconfirm>
                <el-button v-permission="['/system/user/edited']" type="text" size="small" @click.prevent="editedUserForm(scope.row)">edited</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
        <div class="page-pagination">
          <el-pagination
            :current-page="page.current"
            :page-sizes="[15, 30, 100, 300]"
            :page-size="page.size"
            layout="sizes, prev, pager, next"
            :total="page.total"
            @size-change="pageFilterHandler"
            @current-change="pageFilterHandler"
          />
        </div>
        <div class="page-confirm-view">
          <el-dialog :visible="dialogFormVisible" :title="isUpdate? '编辑用户信息' : '新增用户'" :show-close="false">
            <el-form ref="dialogForm" :model="dialogForm" label-width="60px">
              <el-form-item label="昵称">
                <el-input v-model="dialogForm.name" placeholder="输入用户名" />
              </el-form-item>
              <el-form-item label="账号">
                <el-input v-model="dialogForm.account" placeholder="输入账号" />
              </el-form-item>
              <el-form-item v-if="!isUpdate" label="密码">
                <el-input v-model="dialogForm.password" placeholder="输入账号" />
              </el-form-item>
              <el-form-item v-if="isUpdate" label="部门" placeholder="选择部门">
                <el-cascader v-model="dialogForm.deptIds" :options="cascaderDeptOptions" :show-all-levels="false" />
              </el-form-item>
              <el-form-item label="角色">
                <el-select v-model="dialogForm.roleIds" multiple placeholder="选择角色">
                  <el-option v-for="item in cascaderRoleOptions" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
              <el-form-item label="电话" prop="age">
                <el-input v-model.number="dialogForm.phone" />
              </el-form-item>
              <el-form-item label="邮箱" prop="age">
                <el-input v-model.number="dialogForm.email" />
              </el-form-item>
            </el-form>
            <template #footer>
              <span class="dialog-footer">
                <el-button @click="cancelForm">取消</el-button>
                <el-button type="primary" @click="confirmForm">确定</el-button>
              </span>
            </template>
          </el-dialog>
        </div>
      </div>
    </div>
    <div class="tree-confirm-view">
      <el-dialog :visible="dialogTreeFormVisible" :title="isTreeUpdate? '编辑部门信息' : '新增部门'" :show-close="false">
        <el-form ref="dialogTreeForm" :model="dialogTreeForm" label-width="60px">
          <el-form-item label="昵称">
            <el-input v-model="dialogTreeForm.name" placeholder="输入部门名" />
          </el-form-item>
        </el-form>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="cancelTreeForm">取消</el-button>
            <el-button type="primary" @click="confirmTreeForm">确定</el-button>
          </span>
        </template>
      </el-dialog>
    </div>
  </div>
</template>
<script>

import managerPage from '@/mixin/manager-page'
import { newUser, pageFilter, edited, deleted } from '@/api/user.js'
import { list as listRoles } from '@/api/role.js'
import { list, newsDept, edited as editedDept, deleted as deletedDept } from '@/api/dept.js'

export default {
  name: `user-manager`,
  mixins: [managerPage],
  data() {
    return {
      treeDatas: [],
      defaultProps: {
        children: 'childrens',
        label: 'name'
      },
      page: {
        current: 1,
        size: 15,
        total: 1000,
        orders: [],
        filter: {},
        records: []
      },
      loadingTable: false,
      dialogFormVisible: false,
      dialogForm: {},
      isUpdate: false,
      dialogTreeFormVisible: false,
      dialogTreeForm: {},
      isTreeUpdate: false,
      cascaderDeptOptions: [],
      cascaderRoleOptions: [],
      mapRoleId2Name: {},
      mapDeptId2Name: {},
      loadingTree: false
    }
  },
  async mounted() {
    await this.initDept()
    await listRoles().then(rsp => {
      let data = []
      if (rsp && rsp.code === 200) {
        data = rsp.data || []
      }
      this.mapRoleId2Name = {}
      data.forEach(element => {
        this.mapRoleId2Name[element.id] = element.name
        this.cascaderRoleOptions.push({ value: element.id, label: element.name })
      })
    })
    const selectId = ((this.treeDatas || [])[0] || {}).id || null
    this.$nextTick(() => {
      selectId && this.$refs.deptTree.setCheckedKeys([selectId])
    })
    this.page.filter.deptId = selectId
    await this.pageFilterHandler()
  },
  methods: {
    initDept() {
      this.loadingTree = true
      return list().then(rsp => {
        let data = []
        if (rsp && rsp.code === 200) {
          data = rsp.data || []
        }
        this.mapDeptId2Name = {}
        data.forEach(element => {
          this.mapDeptId2Name[element.id] = element.name
        })
        this.cascaderDeptOptions = this.convertSelect(null, data)
        this.treeDatas = [{ id: null, pid: null, name: '组织架构', childrens: this.convertTree(null, data) }]
        this.loadingTree = false
        this.page.filter.deptId = null
      }).catch(e => {
        this.$message.error('查询失败')
        console.error('查询失败', e)
        this.loadingTree = false
      })
    },
    clickdNode(data, node, nodeEl) {
      const nodeData = data || node.data
      this.menuData = nodeData
      this.page.filter.deptId = nodeData.id
      this.pageFilterHandler()
    },
    addNode(node) {
      let nodes = []
      let pid = null
      if (node) {
        nodes = node.data.childrens || []
        pid = node.data.id
      } else {
        nodes = this.treeDatas[0].childrens
      }
      this.isUpdate = false
      this.dialogTreeFormVisible = true
      this.dialogTreeForm = { nodes, pid }
    },
    editedNode(node) {
      let data = {}
      if (node) {
        data = node.data || {}
      }
      this.isUpdate = true
      this.dialogTreeFormVisible = true
      this.dialogTreeForm = { id: data.id, pid: data.pid, name: data.name }
    },
    removeNode(node) {
      console.log(node)
      deletedDept({ id: node.data.id }).then(async rsp => {
        if (rsp.data) {
          await this.initDept()
          await this.pageFilterHandler()
          this.$message.success('处理成功')
        } else {
          this.$message.error('处理失败')
        }
      }).catch(e => {
        this.$message.error('处理失败')
        console.error('处理失败', e)
      })
    },
    sortChange(sortData) {
      const { order, prop } = sortData
      const column = prop
      let asc = true
      if (order === 'descending') {
        asc = false
      }
      const orders = [{ column, asc }]
      this.$set(this.page, 'orders', orders)
      this.pageFilterHandler()
    },
    refreshPageFilter() {
      this.page.filter = {}
    },
    submitPageFilter() {
      this.pageFilterHandler()
    },
    newUserForm() {
      this.isUpdate = false
      this.dialogFormVisible = true
      this.dialogForm = { roleIds: [], deptIds: [this.page.filter.deptId] }
    },
    editedUserForm(row) {
      this.isUpdate = true
      this.dialogFormVisible = true
      this.dialogForm = { ...row, roleIds: row.roleIds || [], deptIds: row.deptId ? [row.deptId] : [] }
    },
    deletedUser(id) {
      deleted({ id }).then(rsp => {
        if (rsp.data) {
          this.$message.success('删除成功')
          this.pageFilterHandler()
        } else {
          this.$message.error('删除失败')
        }
      }).catch(e => {
        this.$message.error('删除失败')
        console.error('删除失败', e)
      })
    },
    confirmForm() {
      let callback
      if (this.isUpdate) {
        const deptIds = (this.dialogForm || {}).deptIds || [null]
        callback = edited({ ...this.dialogForm, deptId: deptIds[deptIds.length - 1] })
      } else {
        callback = newUser({ ...this.dialogForm, deptId: this.dialogForm.deptIds[0] })
      }
      callback.then(async rsp => {
        if (rsp.data) {
          await this.pageFilterHandler()
          this.cancelForm()
          this.$message.success('处理成功')
        } else {
          this.$message.error('处理失败')
        }
      }).catch(e => {
        this.$message.error('处理失败')
        console.error('处理失败', e)
      })
    },
    confirmTreeForm() {
      let callback
      if (this.isUpdate) {
        callback = editedDept({ name: this.dialogTreeForm.name, pid: this.dialogTreeForm.pid, id: this.dialogTreeForm.id })
      } else {
        callback = newsDept({ name: this.dialogTreeForm.name, pid: this.dialogTreeForm.pid })
      }
      callback.then(async rsp => {
        if (rsp.data) {
          await this.initDept()
          this.cancelTreeForm()
          await this.pageFilterHandler()
          this.$message.success('处理成功')
        } else {
          this.$message.error('处理失败')
        }
      }).catch(e => {
        this.$message.error('处理失败')
        console.error('处理失败', e)
      })
    },
    cancelForm() {
      this.dialogFormVisible = false
    },
    cancelTreeForm() {
      this.dialogTreeFormVisible = false
    },
    pageFilterHandler() {
      this.loadingTable = true
      return pageFilter({ ...this.page, records: null }).then(rsp => {
        if (rsp && rsp.code === 200) {
          if (rsp.data) {
            this.page.records = rsp.data.records || []
            this.page.total = rsp.data.total || this.page.total
          }
        }
        this.loadingTable = false
      }).catch(e => {
        this.$message.error('查询失败')
        console.error('查询失败', e)
        this.loadingTable = false
      })
    },
    convertSelect(pid, data) {
      pid = pid || 0
      const children = []
      data.forEach(item => {
        if (pid === (item.pid || 0)) {
          children.push({ value: item.id, label: item.name })
        }
      })
      if (children.length === 0) {
        return null
      }
      children.forEach(item => {
        item.children = this.convertSelect(item.value, data)
      })
      return children
    },
    convertTree(pid, data) {
      pid = pid || 0
      const childrens = []
      data.forEach(item => {
        if (pid === (item.pid || 0)) {
          childrens.push(item)
        }
      })
      if (childrens.length === 0) {
        return []
      }
      childrens.forEach(item => {
        item.childrens = this.convertTree(item.id, data)
      })
      return childrens
    }
  }
}
</script>

<style lang="scss" scoped>
.user-manager-container{
  display: flex;
  position: absolute;
  height: 100%;
  width: 100%;
  padding: 5px;
  .dept-tree-container{
    padding: 15px 0 0 0px;
    width: 300px;
    height: 100%;
    overflow: hidden;
    position: relative;
    .dept-tree-tools{
      position: absolute;
      top: 10px;
      right: 10px;
      font-size: 18px;
      z-index: 2;
      .tree-dept-tools {
        margin: 0 4px;
        cursor: pointer;
      }
    }
    .dept-tree-container{
      height: 100%;
      width: 100%;
      overflow: scroll;
      position: relative;
      &::-webkit-scrollbar {
        width: 7px;
        height: 8px;
      }
      &::-webkit-scrollbar-thumb {
        background-color: rgba(144,147,153,.3);
        border-radius: 2px;
        box-shadow: inset 0 0 6px rgb(0 0 0 / 20%);
      }
      &::-webkit-scrollbar-track {
        background-color: rgba(0,0,0,.05);
      }
      .custom-tree-node {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: space-between;
        font-size: 14px;
        padding-right: 8px;
        .tree-node-tools {
          margin: 0 3px;
        }
      }
    }
  }
  .manager-page-container{
    position: initial;
    overflow: hidden;
    padding: 0 10px;
  }
}
</style>

<style lang="scss">

  .tree-confirm-view{
    .el-dialog__wrapper .el-dialog {
      width: 520px;
      padding-right: 50px;
      .el-dialog__body{
        .el-form{
          label{
            width: 60px;
          }
          .el-form-item__content{
            width: 400px;
            .el-select.el-select--medium{
              width: 100%;
            }
            .el-cascader.el-cascader--medium{
              width: 100%;
            }
          }
        }
      }
      .el-dialog__footer{
        height: 60px;
        .dialog-footer{
          transform: translateX(-50%);
          left: 50%;
          position: absolute;
        }
      }
    }
  }
@import '@/scss/manager-page.scss';
</style>
